/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.third.jg.report.freight.information.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.third.jg.report.freight.information.constant.AhReportConstant;
import org.jeecg.modules.third.jg.report.freight.information.constant.OrdosReportConstant;
import org.jeecg.modules.third.jg.report.freight.information.constant.enums.ReportDocTypeEnum;
import org.jeecg.modules.third.jg.report.freight.information.dto.AppInfoDTO;
import org.jeecg.modules.third.jg.report.freight.information.model.ExchangeModel;
import org.jeecg.modules.third.jg.report.freight.information.model.R;
import org.jeecg.modules.third.jg.report.freight.information.util.ordos.OrdosRsaUtils;
import org.jeecg.modules.third.jg.report.freight.information.util.sm.SM2Util;
import org.jeecg.modules.third.jg.report.freight.information.util.sm.SM4Util;
import org.jeecg.modules.third.oapi.alct56.constant.OapiAlct56Constant;
import org.jeecg.modules.wlhy.utils.HyCfgUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 鄂尔多斯平台上报服务
 */
@Service
@Slf4j
public class OrdosReportPlatformService {

    @Resource
    private  RedisUtil redisUtil;

    @Resource
    private BaseCommonService baseCommonService;

    @Value(value="${ordos-report-platform.domain:}")
    private String reportPlatformDomain;

    private String username;

    private String password;

    @Value(value="${ordos-report-platform.publicKey:}")
    private String publickey;

    @Value(value="${ordos-report-platform.accessKey:}")
    private String accessKey;

    private String appId;

    private String appSecurity;

    private String appSenderCode;

    private String appDebugSystem;

    public AppInfoDTO getAppInfo() {
        return AppInfoDTO.builder()
                .appId(this.appId)
                .appSecurity(this.appSecurity)
                .enterpriseSenderCode(this.appSenderCode)
                .debugSystem(this.appDebugSystem)
                .build();
    }


    public void setReportInfo(String reportPlatformDomain,
                              String username,
                              String password,
                              String publickey,
                              String appId,
                              String appSecurity,
                              String appSenderCode,
                              String appDebugSystem) {
        //联调状态的App需要设置debugSystem
        if ("0".equals(appDebugSystem)) {
            appDebugSystem = "debugSystem";
        }

        this.reportPlatformDomain = reportPlatformDomain;
        this.username = username;
        this.password = password;
        this.publickey = publickey;
        this.appId = appId;
        this.appSecurity = appSecurity;
        this.appSenderCode = appSenderCode;
        this.appDebugSystem = appDebugSystem;
    }


    private String getLoginToken() throws Exception {

        //鄂尔多斯市监管平台
        if(!HyCfgUtil.isUsed("ordos_report")){
            throw new JeecgBootException("鄂尔多斯上报服务暂未开启,请联系管理员。");
        }

        //配置参数-------------
        if (StrUtil.isEmpty(this.reportPlatformDomain) ||StrUtil.isEmpty(this.publickey) || StrUtil.isEmpty(this.accessKey)) {
            log.error("鄂尔多斯上报参数配置错误,请联系管理员。 {} -> {} -> {}", this.reportPlatformDomain, this.publickey, this.accessKey);
            throw new JeecgBootException("鄂尔多斯上报参数配置错误,请联系管理员。");
        }
        //-----------------

        Object tokenObject = redisUtil.get(OrdosReportConstant.API_REPORT_TOKEN_KEY + "_" + this.username);
        if (tokenObject != null){
            return tokenObject.toString();
        }

        Map <String, String> params = new HashMap <>();
        params.put("accessKey", this.accessKey);

        try {
            String url = reportPlatformDomain + OrdosReportConstant.AUTH_URL;
            log.info("鄂尔多斯市监管获取token请求 -> {} -> {}", url, JSONUtil.toJsonStr(params));
            String authResult = HttpUtil.post(url, JSONUtil.toJsonStr(params));
            log.info("鄂尔多斯市获取token回执 <- {}", authResult);
            R result = JSON.parseObject(authResult, R.class);
            if (result.getCode() == 200 && StringUtils.isNotEmpty(result.getToken())) {
                String token = result.getToken();
                redisUtil.set(OrdosReportConstant.API_REPORT_TOKEN_KEY + "_" + this.username,
                        token, OrdosReportConstant.API_REPORT_TOKEN_KEY_EXPIRE);
                return token;
            } else {
                log.info("OrdosReportConstant getLoginToken authResult url:{} | jsonObject:{}"
                        ,url,params.toString());
                throw new Exception("token获取异常," + result.getMsg()+result.getData());
            }
        } catch (Exception e) {
            log.error("鄂尔多斯市监管获取token请求异常 :{}" ,e.getMessage());
            e.printStackTrace();
        }

        return "";
    }


    private String messageAssembly(String jsonString) throws NoSuchAlgorithmException, InvalidKeySpecException {
        return OrdosRsaUtils.publicEncrypt(jsonString, OrdosRsaUtils.getPublicKey(this.publickey));
    }

    /**
     * 发送上报
     * @param jsonString
     */
    public String sendReport(String sendUrl, String jsonString) throws Exception {
        String sendResult = StringUtils.EMPTY;
        try {
            String token = getLoginToken();
            if (StrUtil.isEmpty(token)) {
                return null;
            }

            String bodys = messageAssembly(jsonString);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("data", bodys);

            String url = reportPlatformDomain + sendUrl;
            log.info("上报鄂尔多斯市监管, {} -> {} : {} -> {}", token, url, jsonString, jsonObject.toString());

            HttpResponse response = HttpRequest.post(url)
                    .header("Content-Type", "application/json; UTF-8")
                    .header("Authorization", token)
                    .body(jsonObject.toString())
                    .execute();

            sendResult = response.body();
            log.info("上报鄂尔多斯市监管回执 <- {}", sendResult);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("上报鄂尔多斯市监管数据异常 :{}", e.getMessage());
        }
        return sendResult;
    }

}
